home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / login.zip / LOGIN.C < prev    next >
C/C++ Source or Header  |  1991-02-03  |  9KB  |  354 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <direct.h>
  4. #include <dos.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8.  
  9. #include "login.h"
  10.  
  11. char    *zgets(char *buffer, int echo);
  12. int     zputs(char *str);
  13.  
  14. struct    usr  *verify();              /* routine to validate user */
  15. char    *getfld();                /* pluck field n from a buffer */
  16.  
  17. char    *motd, *passwd, *logfile;       /* for default overrides */
  18. int     root = ROOT, debug = 0, logmode = 0, verbose = 0, message = 0;
  19.  
  20. void
  21. main(argc, argv)
  22. int     argc;
  23. char    **argv;
  24. {
  25.     struct    usr     *usr, home;
  26.     extern    char *optarg;
  27.     extern    int optind;
  28.     char    linbuf[256];
  29.     int     n, errflg = 0, c;
  30.  
  31.     while ((c = getopt(argc, argv, "dvlm")) != EOF) {
  32.         switch (c) {
  33.         case 'd':               /* enable debugging output */
  34.             ++debug;
  35.             break;
  36.         case 'm':               /* enable message of day output */
  37.             ++message;
  38.             break;
  39.          case 'v':              /* enable verbose output mode */
  40.             ++verbose;
  41.             break;
  42.          case 'l':              /* enable user activity logging mode */
  43.             ++logmode;
  44.             break;
  45.         default:                /* error */
  46.             errflg++;
  47.             break;
  48.         }
  49.     }
  50.  
  51.     /* override the PASSWD file path */
  52.     if ((passwd = getenv("PASSWD")) == NULL)
  53.         passwd = PASSWD;
  54.  
  55.     /* override the LOGFILE file path */
  56.     if ((logfile = getenv("LOGFILE")) == NULL)
  57.         logfile = LOGFILE;
  58.  
  59.     /* override the MOTD file path */
  60.     if ((motd = getenv("MOTD")) == NULL)
  61.         motd = MOTD;
  62.  
  63.     /* override the ROOT user id */
  64.     if (getenv("ROOT"))
  65.         root = atoi(getenv("ROOT"));
  66.  
  67.     if (errflg) {
  68.         fprintf(stderr, USAGE);
  69.         exit(9);
  70.     }
  71.  
  72.     /* set up master HOME environment, so that drive  */
  73.     /* and directory changes are undone between users */
  74.     if (getcwd(home.home, 80) == NULL)        /* current master directory */
  75.         error(4);
  76.     _dos_getdrive(&home.drive);             /* use current logged drive */
  77.  
  78.     fprintf(stderr, "%s", SIGNON);
  79.  
  80.     /* stay here */
  81.     while (1) {
  82.         zputs("\n\rlogin: ");               /* show login prompt */
  83.         zgets(linbuf, ECHO);
  84.         if (!strlen(linbuf))
  85.             continue;
  86.  
  87.         /* validate user name */
  88.         if ((usr = verify(linbuf)) == (struct usr *)NULL)
  89.             zputs("\nlogin incorrect.\n");
  90.         else {
  91.             if (verbose)
  92.                 usrinfo(usr);                /* show user info */
  93.  
  94.             if (message)                    /* show message of day */
  95.                 domotd(motd);
  96.  
  97.             if (n = setinfo(usr))           /* set user environment */
  98.                 error(n);                    /* (even if root) */
  99.  
  100.             if (usr->uid == root)            /* if "root" ID, just exit */
  101.                 exit(0);
  102.             else {
  103.  
  104.                 if (logmode)
  105.                     loginfo(usr, 'I');      /* record user login */
  106.  
  107.                 showinfo(usr, "in");
  108.  
  109.                 system(usr->shell);         /* execute command or shell */
  110.  
  111.                 showinfo(usr, "out");
  112.  
  113.                 if (logmode)
  114.                     loginfo(usr, 'O');      /* record user log out */
  115.             }
  116.  
  117.             if (n = setinfo(&home))         /* reset master environment */
  118.                 error(n);
  119.         }
  120.     }
  121. }
  122.  
  123. /* show user some handy info */
  124. showinfo(struct usr *u, char *m)
  125. {
  126.     time_t    t;
  127.  
  128.     time (&t);
  129.     fprintf(stderr, "\nLogged %s: %.24s   Drive=%c:   Path=%s\n",
  130.         m, ctime(&t), u->drive+'@', u->home);
  131.     return (0);
  132. }
  133.  
  134.  
  135. /* set user environment per the password file */
  136. setinfo(struct usr * u)
  137. {
  138.     unsigned a;
  139.  
  140.     _dos_setdrive(u->drive, &a);            /* set drive */
  141.     _dos_getdrive(&a);                        /* verify drive was selected */
  142.     if (a != u->drive)                        /* error */
  143.         return (1);
  144.     if (chdir(u->home))                     /* set new home directory */
  145.         return (2);
  146.     return (0);
  147. }
  148.  
  149. /* display user environment per the password file */
  150. usrinfo(struct usr * u)
  151. {
  152.     char *p;
  153.  
  154.     fprintf(stderr, "\n");
  155.     fprintf(stderr, "name.......%s\n", u->name);        /* 0 */
  156.     fprintf(stderr, "user id....%d\n", u->uid);         /* 1 */
  157.     p = decrypt(u->passwd);
  158.     if (debug)
  159.         fprintf(stderr, "password...%s\n", p);          /* 2 */
  160.     if (p)
  161.         free(p);
  162.     fprintf(stderr, "drive......%c\n", u->drive + '@'); /* 3 */
  163.     fprintf(stderr, "home.......%s\n", u->home);        /* 4 */
  164.     fprintf(stderr, "shell......%s\n", u->shell);       /* 5 */
  165. }
  166.  
  167. /* log user activity in log file */
  168. loginfo(struct usr * u, char m)
  169. {
  170.     FILE    *fp;
  171.     char    db[9];
  172.     char    tb[9];
  173.  
  174.     /* open log file */
  175.     if ((fp = fopen(logfile, "a+")) == NULL) {
  176.         error(5);
  177.         return(0);
  178.     }
  179.  
  180.     /* if file is new, add header */
  181.     if ((filelength(fileno(fp))) == 0) {
  182.         fprintf(fp, "T|  Date     Time  |   User Name   |ID#|D| User Home Directory |  Command/Shell\n");
  183.         fprintf(fp, "-+-----------------+---------------+---+-+---------------------+------------------\n");
  184.                   /* I|02/01/91 21:18:36|mfl            |  1|D|\games                |C:\COMMAND.COM    */
  185.                   /* O|02/01/91 21:18:36|mfl            |  1|D|\games                |C:\COMMAND.COM    */
  186.     }
  187.     _strdate(db);        /* get date */
  188.     _strtime(tb);        /* get time */
  189.     fprintf(fp, "%c|%s %s|%-15s|%3d|%c|%-21s|%-20s\n",
  190.         m, db, tb, u->name, u->uid, u->drive + '@', u->home, u->shell);
  191.     fclose(fp);
  192.     return (0);
  193. }
  194.  
  195. domotd(f)
  196. char    *f;
  197. {
  198.     FILE    *fp;
  199.     char    linbuf[256];
  200.  
  201.     /* open daily message file */
  202.     if ((fp = fopen(f, "r")) == NULL) {
  203.         error(7);
  204.         return (0);
  205.     }
  206.  
  207.     /* no lines in file */
  208.     if ((filelength(fileno(fp))) == 0) {
  209.         error(8);
  210.         return (0);
  211.     }
  212.  
  213.     fprintf(stderr, "\n\r");
  214.     /* read lines from the MOTD file */
  215.     while (fgets(linbuf, BUFSIZ, fp))
  216.         fprintf(stderr, "%s", linbuf);
  217.     fclose(fp);
  218.     zputs("\n\rPress any key...");
  219.     zgetch();
  220. }
  221.  
  222.  
  223. /* validate user, assign default values per the password file */
  224. struct usr *
  225. verify(char *l)
  226. {
  227.     FILE    *fp;
  228.     static    struct usr u;
  229.     char    linbuf[256];
  230.     char    *comspec, *p, shell[80];
  231.     int     found = 0;
  232.  
  233.     /* open password file */
  234.     if ((fp = fopen(passwd, "r")) == NULL) {
  235.         error(3);
  236.         return ((struct usr *)NULL);
  237.     }
  238.  
  239.     /* read lines from the PASSWD file */
  240.     while (!found && fgets(linbuf, BUFSIZ, fp)) {
  241.         memset(&u, '\0', sizeof (struct usr));      /* clean up structure */
  242.  
  243.         if (*linbuf == '#')                         /* '#' denotes comment */
  244.             continue;
  245.  
  246.         p = getfld(linbuf, 0, ':');                 /* user name */
  247.         strcpy(u.name, p);     /* user name */
  248.         if (p)
  249.             free(p);
  250.  
  251.         if (!strcmp(u.name, l))                     /* name matches */
  252.             found = 1;
  253.         else
  254.             continue;
  255.  
  256.         if ((p = strchr(linbuf, '\n')) != NULL)     /* zap new-lines */
  257.             *p = '\0';
  258.  
  259.         p = getfld(linbuf, 1, ':');                 /* user ID */
  260.         u.uid = atoi(p);                            /* user ID */
  261.         if (p)
  262.             free(p);
  263.  
  264.         p = getfld(linbuf, 2, ':');                 /* user password */
  265.         strcpy(u.passwd, p);                        /* user password */
  266.         if (p)
  267.             free(p);
  268.  
  269.         p = getfld(linbuf, 3, ':');                 /* disk drive */
  270.         u.drive = *p == '\0' ? 0 : *p - '@';        /* set to 0 if none */
  271.         if (p)
  272.             free(p);
  273.  
  274.         p = getfld(linbuf, 4, ':');                 /* home directory */
  275.         strcpy(u.home, p);                            /* home directory */
  276.         if (p)
  277.             free(p);
  278.  
  279.         p = getfld(linbuf, 5, ':');                 /* command/shell */
  280.         strcpy(shell, p);                            /* command/shell */
  281.         if (p)
  282.             free(p);
  283.  
  284.         if (*u.home == '\0')                        /* no HOME specified */
  285.             if (getcwd(u.home, 80) == NULL)         /* current directory */
  286.                 error(4);
  287.     }
  288.  
  289.     /* prompt for password for invalid names and if a password is specified */
  290.     if (!found || *u.passwd != '\0') {              /* password required or */
  291.         zputs("\npassword: ");                      /* invalid name entered */
  292.         zgets(linbuf, NOECHO);
  293.     }
  294.     /* if name and password (if any) matches */
  295.     p = decrypt(u.passwd);
  296.     if (found && (!strcmp(p, linbuf) || *u.passwd == '\0')) {
  297.         if (u.drive == 0)                            /* no drive specified */
  298.             _dos_getdrive(&u.drive);                /* use current drive */
  299.  
  300.         if ((comspec = (char *) getenv("COMSPEC")) == NULL) {
  301.             comspec = "X:\command.com";
  302.             *comspec = (char )u.drive + '@';    /* use current drive */
  303.         }
  304.         strcpy(u.shell, shell);         /* execute whatever as default */
  305.         /* if "shell" specified, use COMSPEC to find "command.com" */
  306.         if (!strncmp(strupr(shell), "SHELL", 5))
  307.             strcpy(u.shell, comspec);
  308.         else if (p = strchr(shell, '.')) {
  309.             if (!strcmp(strupr(p), ".BAT"))     /* execute batch file */
  310.                 sprintf(u.shell, "%s /C %s", comspec, shell);
  311.         }
  312.     } else
  313.         found = 0;
  314.     if (p)
  315.         free(p);
  316.     fclose(fp);
  317.     return (found ? &u : (struct usr *) NULL);
  318. }
  319.  
  320. char *
  321. zgets(char *str, int echo)
  322. {
  323.     char    c, *save = str;
  324.  
  325.     while ((c = zgetch()) != '\n') {
  326.         *str++ = c;
  327.         if (echo)
  328.             putch(c);
  329.     }
  330.     *str = '\0';
  331.     return save;
  332. }
  333.  
  334. int
  335. zgetch()
  336. {
  337.     char    c;
  338.  
  339.     c = bdos(7, 0, 0);
  340.     return (c == '\r') ? '\n' : c;
  341. }
  342.  
  343. zputs(char *str)
  344. {
  345.     char    c;
  346.  
  347.     while (c = *str++) {
  348.         if (c == '\n')
  349.             putch('\r');
  350.         putch(c);
  351.     }
  352.     return 0;
  353. }
  354.